In this note, we study the R package owidR for importing data from Our World in Data.

1 References

The package official site contains other links. When you quote the package, use the link to the official site.

In general, README gives a short introduction to the package, a Manual, the comprehensive descriptions of each function, and a Vignette, a practical introduction containing examples and applications.

2 Introduction

This package acts as an interface to Our World in Data datasets, allowing for an easy way to search through data used in over 3,000 charts and load them into the R environment.

2.1 Setup

2.1.1 Installation

Run the following for the first time

install.packages("owidR")

2.1.2 Load the package

library(owidR)
library(tidyverse) 

The package automatically load a part of tidyverse, e.g., dplyr, ggplot, …. Since it works well with the schemetidyverse, it is better to load tidyverse with it.

The creator of this package also suggests loading packages plm for panels of data, and texreg for displaying models, but let us start without them until we actually use them. For panel data, see, for example, the site](https://www.aptech.com/blog/introduction-to-the-fundamentals-of-panel-data/).

2.2 Core functions

2.2.1 List of core functions

In this package, chart is close to data, and chart id is a data indicator.

  • owid: Get a dataset used in an OWID chart
  • owid_covid: Get the Our World in Data covid-19 dataset
  • owid_search: Search the data sources used in OWID charts
  • owid_source: A function to get source information from an OWID dataset and display it in the R console.
  • pal_owid: Colour palettes based on the colours used by Our World in Data
  • view_chart: A function that opens the original OWID chart in your browser
  • world_map_data: Function that returns a simple feature collection of class sf. Map data is from naturalearthdata.com. Designed to be used internally.

2.2.2 Usage

2.2.2.2 owid

Get a dataset used in an OWID chart

owid(chart_id = NULL, rename = NULL, tidy.date = TRUE, ...)

chard_id: The chart_id as returned by owid_search, which is combined with ‘-’. Don’t mix up with the chart titles.

rename: Rename the value column. Currently only works if their is just one value col- umn.

  • Example
emissions <- owid("per-capita-ghg-emissions")
emissions
rights <- owid("human-rights-scores")
rights

Note.

  1. You can use rename to change column names. For example,
owid("per-capita-ghg-emissions", rename = "ghgPcap")
  1. Since until after importing the data, you never know the original column name, and how many columns are for indicators. It is natural to change column names using dpyr::rename. In the next example, I used Total including LUCF. However, ‘Total including LUCF’ and “Total including LUCF” work as well.
emissions %>% rename(ghgPcap = `Total including LUCF`)
  1. If there are more than one variables to rename, use vector notation as follows. Here top_n(1) is same as slice(1), and gives the first row only.
owid("electoral-democracy") %>% top_n(1)
Selecting by electdem_vdem_low_owid
owid("electoral-democracy", rename = c("electoral_democracy", "vdem_high", "vdem_low"))
  1. You can use dplyr::rename, and keep the record of renaming column names.
(democracy <- owid("electoral-democracy"))
democracy <- democracy %>% 
  rename(`electoral_democracy` = `Electoral democracy`,  
         `vdem_high` = `electdem_vdem_high_owid`, 
         `electdem_vdem_low_owid` = `electdem_vdem_low_owid`)
democracy

2.2.2.3 owid_source

A function to get source information from an OWID dataset and display it in the R console.

owid_source(data)
  • Example
owid_source(emissions)
Dataset Name: Our World in Data based on Climate Analysis Indicators Tool (CAIT).

Published By: CAIT Climate Data Explorer via Climate Watch

Link: https://www.climatewatchdata.org/data-explorer/historical-emissions

Emissions are measured in tonnes of carbon dioxide equivalents (CO₂e), based on 100-year global warming potential factors for non-CO₂ gases.

Emissions are broken down by sector. Further information on sector definitions is available <a href="https://ourworldindata.org/ghg-emissions-by-sector">here</a>.
owid_source(rights)
Dataset Name: Fariss et al. (2020)

Published By:  Fariss CJ, Kenwick MR, Reuning K. Estimating one-sided-killings from a robust measurement model of human rights. Journal of Peace Research. 2020;57(6):801-814. doi:10.1177/0022343320965670

Link: https://dataverse.harvard.edu/dataset.xhtml?persistentId=doi:10.7910/DVN/RQ85GK

This dataset provides the human rights protection scores by Fariss et al. (2020), first developed by Schnakenberg and Fariss (2014).

You can download the code and complete dataset, including supplementary variables, from GitHub: https://github.com/owid/notebooks/tree/main/BastianHerre/human_rights

2.2.2.4 view_chart

A function that opens the original OWID chart in your browser

view_chart(x)
  • x Either a tibble returned by owid(), or a chart_id.

  • Example

The first one uses the chart, i.e., the tibble returned by owid(), and the second, chart_id. You can also embed in your R Markdown file by copying Embed iframe clink from Share botton at the bottom right corner.

firearm_suicide <- owid("suicide-rate-by-firearm")
    view_chart(firearm_suicide)
view_chart("electoral-democracy")
view_chart("share-of-individuals-using-the-internet")

2.2.2.5 pal_owid

Colour palettes based on the colours used by Our World in Data

2.2.2.6 owid_covid

owid_covid: Get the Our World in Data covid-19 dataset

owid_covid()

See the detail at the GitHub site.

  • Example
covid <- owid_covid()
covid %>% filter(location == "Japan")

3 Examples

The following is based on the presentation and the first two R Notebook files created by Professor Kaizoji.

3.1 Human Rights- modified from README

Lets use the core functions to get data on how human rights have changed over time. First by searching for charts on human rights.

owid_search("human rights") %>% as_tibble()

Let’s use the human rights protection dataset.

rights <- owid("human-rights-protection")
rights

ggplot2 makes it easy to visualise our data.

rights %>% 
  filter(entity %in% c("United Kingdom", "France", "United States", "Japan")) %>%  
  ggplot(aes(year, `Human rights protection`, colour = entity)) +
  geom_line()

3.2 Internet - modified from vignette

owid_search("internet") %>% as_tibble()

Get a dataset used in an OWID chart.

internet <- owid("share-of-individuals-using-the-internet", rename = "internet_use")
internet

Get source information on an OWID dataset

owid_source(internet)
Dataset Name: International Telecommunication Union (via World Bank)

Published By: World Development Indicators - World Bank (2022.05.26)

Link: https://datacatalog.worldbank.org/search/dataset/0037712/World-Development-Indicators

A function that opens the original OWID chart in your browser.

view_chart(internet)

Plot an owid dataset

owid_plot(internet, filter = "World") +
  labs(title = "Share of the World Population using the Internet") +
  scale_y_continuous(limits = c(0, 100))+
  theme_owid()
Loading required namespace: showtext
Failed with error:  ‘there is no package called ‘showtext’’
Warning: importing fonts requires the showtext pacakgeLoading required namespace: showtext
Failed with error:  ‘there is no package called ‘showtext’’
Warning: importing fonts requires the showtext pacakge

owid_plot(internet, summarise = FALSE, filter = c("United Kingdom", "Spain", "Russia", "Egypt", "Nigeria")) +
  labs(title = "Share of Population with Using the Internet") +
  scale_y_continuous(limits = c(0, 100), labels = scales::label_number(suffix = "%")) # The labels argument allows you to make it clear that the value is a percentage
Loading required namespace: showtext
Failed with error:  ‘there is no package called ‘showtext’’
Warning: importing fonts requires the showtext pacakgeWarning: 'scale_colour_owid' is deprecated.
See help("Deprecated")

creating a choropleth map

owid_map(internet, year = 2017) +
  labs(title = "Share of Population Using the Internet, 2017")
Loading required namespace: showtext
Failed with error:  ‘there is no package called ‘showtext’’
Warning: importing fonts requires the showtext pacakge

3.3 Democracy - modified from vignette

owid_search("democrac") %>% as_tibble()
democracy <- owid("electoral-democracy", rename = c("electoral_democracy", "vdem_high", "vdem_low"))
democracy
owid_source(democracy)
Value:  

Dataset Name: OWID based on V-Dem (v12) and Lührmann et al. (2018)

Published By: Our World in Data, Bastian Herre

Link: http://v-dem.net/vdemds.html

This dataset provides information on democracy and human rights, using data from the Varieties of Democracy project (v12), and the Regimes of the World classification by Lührmann et al. (2018).

We expand the countries and years covered, and refine the coding of the Regimes of the World classification. You can read a detailed description of the data in these posts:
https://ourworldindata.org/regimes-of-the-world-data
https://ourworldindata.org/vdem-electoral-democracy-data
https://ourworldindata.org/vdem-human-rights-data

You can download the code and complete dataset, including supplementary variables, from GitHub: https://github.com/owid/notebooks/tree/main/BastianHerre/democracyValue:  

Dataset Name: OWID based on V-Dem (v12) and Lührmann et al. (2018)

Published By: Our World in Data, Bastian Herre

Link: http://v-dem.net/vdemds.html

This dataset provides information on democracy and human rights, using data from the Varieties of Democracy project (v12), and the Regimes of the World classification by Lührmann et al. (2018).

We expand the countries and years covered, and refine the coding of the Regimes of the World classification. You can read a detailed description of the data in these posts:
https://ourworldindata.org/regimes-of-the-world-data
https://ourworldindata.org/vdem-electoral-democracy-data
https://ourworldindata.org/vdem-human-rights-data

You can download the code and complete dataset, including supplementary variables, from GitHub: https://github.com/owid/notebooks/tree/main/BastianHerre/democracyValue:  

Dataset Name: OWID based on V-Dem (v12) and Lührmann et al. (2018)

Published By: Our World in Data, Bastian Herre

Link: http://v-dem.net/vdemds.html

This dataset provides information on democracy and human rights, using data from the Varieties of Democracy project (v12), and the Regimes of the World classification by Lührmann et al. (2018).

We expand the countries and years covered, and refine the coding of the Regimes of the World classification. You can read a detailed description of the data in these posts:
https://ourworldindata.org/regimes-of-the-world-data
https://ourworldindata.org/vdem-electoral-democracy-data
https://ourworldindata.org/vdem-human-rights-data

You can download the code and complete dataset, including supplementary variables, from GitHub: https://github.com/owid/notebooks/tree/main/BastianHerre/democracy
owid_map(democracy, year = 2015, palette = "YlGn") +
  labs(title = "Electoral Democracy")
Loading required namespace: showtext
Failed with error:  ‘there is no package called ‘showtext’’
Warning: importing fonts requires the showtext pacakge

owid_plot(democracy, summarise = FALSE, filter = c("United Kingdom", "Spain", "Russia", "Egypt", "Nigeria")) +
  labs(title = "electoral-democracy") +
  scale_y_continuous(limits = c(0, 1), labels = scales::label_number(suffix = "%")) # The labels argument allows you to make it clear that the value is a percentage
Loading required namespace: showtext
Failed with error:  ‘there is no package called ‘showtext’’
Warning: importing fonts requires the showtext pacakgeWarning: 'scale_colour_owid' is deprecated.
See help("Deprecated")

#> Warning: 'scale_colour_owid' is deprecated.
#> See help("Deprecated")
gdp <- owid("gdp-per-capita-worldbank", rename = "gdp")

gov_exp <- owid("total-gov-expenditure-gdp-wdi", rename = "gov_exp")

age_dep <- owid("age-dependency-ratio-of-working-age-population", rename = "age_dep")

unemployment <- owid("unemployment-rate", rename = "unemp")

Mutating joins

left_join(): includes all rows in x.

References

data <- internet %>% 
  left_join(democracy) %>% 
  left_join(gdp) %>% 
  left_join(gov_exp) %>% 
  left_join(age_dep) %>% 
  left_join(unemployment)
Joining, by = c("entity", "code", "year")Joining, by = c("entity", "code", "year")Joining, by = c("entity", "code", "year")Joining, by = c("entity", "code", "year")Joining, by = c("entity", "code", "year")

Drawing scatter plot

data %>% 
  filter(year == 2015) %>% 
  ggplot(aes(internet_use, electoral_democracy)) +
  geom_point(colour = "#57677D", na.rm = TRUE) +
  geom_smooth(method = "lm", colour = "#DC5E78", na.rm = TRUE) +
  labs(title = "Relationship Between Internet Use and electoral_democracy", x = "Internet Use", y = "electoral_democracy") +
  theme_owid()
Failed with error:  ‘there is no package called ‘showtext’’

data %>% 
  filter(year == 2015) %>% 
  ggplot(aes(gdp, internet_use)) +
  geom_point(colour = "blue") +
  geom_smooth(method = "gam", colour = "red", level = 0.0) +
  labs(title = "Relationship Between Internet Use and GDP", x = "GDP", y = "Internet Use")

model1 <- lm(electoral_democracy ~ internet_use, data)
summary(model1)

Call:
lm(formula = electoral_democracy ~ internet_use, data = data)

Residuals:
     Min       1Q   Median       3Q      Max 
-0.76097 -0.20192  0.02248  0.18764  0.48558 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)    
(Intercept)  0.4283461  0.0042829  100.01   <2e-16 ***
internet_use 0.0035522  0.0001166   30.46   <2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.2475 on 5311 degrees of freedom
  (1347 observations deleted due to missingness)
Multiple R-squared:  0.1487,    Adjusted R-squared:  0.1485 
F-statistic: 927.7 on 1 and 5311 DF,  p-value: < 2.2e-16
model2 <- lm(gdp ~ internet_use, data)
summary(model2)

Call:
lm(formula = gdp ~ internet_use, data = data)

Residuals:
   Min     1Q Median     3Q    Max 
-35872  -7670  -4496   3306 126683 

Coefficients:
             Estimate Std. Error t value Pr(>|t|)    
(Intercept)  8101.982    276.503   29.30   <2e-16 ***
internet_use  413.174      7.315   56.48   <2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 16350 on 5872 degrees of freedom
  (786 observations deleted due to missingness)
Multiple R-squared:  0.352, Adjusted R-squared:  0.3519 
F-statistic:  3190 on 1 and 5872 DF,  p-value: < 2.2e-16

Creating a table of the results of the regression analysis using texreg. For the first time, install the pacage texreg.

install.packages("texreg")
library(texreg)
models <- list("Model 1" = model1,
               "Model 2" = model2)
screenreg(models, stars = NULL)

================================
              Model 1   Model 2 
--------------------------------
(Intercept)      0.43   8101.98 
                (0.00)  (276.50)
internet_use     0.00    413.17 
                (0.00)    (7.32)
--------------------------------
R^2              0.15      0.35 
Adj. R^2         0.15      0.35 
Num. obs.     5313      5874    
================================
LS0tCnRpdGxlOiAiUiBQYWNrYWdlIGBvd2lkUmAiCm91dHB1dDoKICBodG1sX25vdGVib29rOiAKICAgIHRvYzogeWVzCiAgICB0b2NfZmxvYXQ6IHllcwogICAgaGlnaGxpZ2h0OiB0YW5nbwogICAgdGhlbWU6IGNlcnVsZWFuCiAgICBudW1iZXJfc2VjdGlvbnM6IHllcwogIHBkZl9kb2N1bWVudDoKICAgIHRvYzogeWVzCi0tLQoKPiBJbiB0aGlzIG5vdGUsIHdlIHN0dWR5IHRoZSBSIHBhY2thZ2UgYG93aWRSYCBmb3IgaW1wb3J0aW5nIGRhdGEgZnJvbSBPdXIgV29ybGQgaW4gRGF0YS4KCiMgUmVmZXJlbmNlcwoKVGhlIHBhY2thZ2Ugb2ZmaWNpYWwgc2l0ZSBjb250YWlucyBvdGhlciBsaW5rcy4gV2hlbiB5b3UgcXVvdGUgdGhlIHBhY2thZ2UsIHVzZSB0aGUgbGluayB0byB0aGUgb2ZmaWNpYWwgc2l0ZS4KCiogUGFja2FnZSBPZmZpY2lhbCBTaXRlOiBodHRwczovL0NSQU4uUi1wcm9qZWN0Lm9yZy9wYWNrYWdlPW93aWRSCiAgLSBSZWFkTWU6IGh0dHBzOi8vY3Jhbi5yLXByb2plY3Qub3JnL3dlYi9wYWNrYWdlcy9vd2lkUi9yZWFkbWUvUkVBRE1FLmh0bWwKICAtIE1hbnVhbDogaHR0cHM6Ly9jcmFuLnItcHJvamVjdC5vcmcvd2ViL3BhY2thZ2VzL293aWRSL293aWRSLnBkZgogIC0gVmlnbmV0dGU6IFtDcmVhdGUgYW5kIEFuYWx5c2UgYSBEYXRhc2V0XShodHRwczovL2NyYW4uci1wcm9qZWN0Lm9yZy93ZWIvcGFja2FnZXMvb3dpZFIvdmlnbmV0dGVzL2V4YW1wbGUtYW5hbHlzaXMuaHRtbCkKICAKSW4gZ2VuZXJhbCwgUkVBRE1FIGdpdmVzIGEgc2hvcnQgaW50cm9kdWN0aW9uIHRvIHRoZSBwYWNrYWdlLCBhIE1hbnVhbCwgdGhlIGNvbXByZWhlbnNpdmUgZGVzY3JpcHRpb25zIG9mIGVhY2ggZnVuY3Rpb24sIGFuZCBhIFZpZ25ldHRlLCBhIHByYWN0aWNhbCBpbnRyb2R1Y3Rpb24gY29udGFpbmluZyBleGFtcGxlcyBhbmQgYXBwbGljYXRpb25zLgoKIyBJbnRyb2R1Y3Rpb24KCj5UaGlzIHBhY2thZ2UgYWN0cyBhcyBhbiBpbnRlcmZhY2UgdG8gW091ciBXb3JsZCBpbiBEYXRhXShodHRwczovL291cndvcmxkaW5kYXRhLm9yZykgZGF0YXNldHMsIGFsbG93aW5nIGZvciBhbiBlYXN5IHdheSB0byBzZWFyY2ggdGhyb3VnaCBkYXRhIHVzZWQgaW4gb3ZlciAzLDAwMCBjaGFydHMgYW5kIGxvYWQgdGhlbSBpbnRvIHRoZSBSIGVudmlyb25tZW50LgoKIyMgU2V0dXAKCiMjIyBJbnN0YWxsYXRpb24KClJ1biB0aGUgZm9sbG93aW5nIGZvciB0aGUgZmlyc3QgdGltZQoKYGBge3IgZXZhbD1GQUxTRX0KaW5zdGFsbC5wYWNrYWdlcygib3dpZFIiKQpgYGAKCiMjIyBMb2FkIHRoZSBwYWNrYWdlCgpgYGB7cn0KbGlicmFyeShvd2lkUikKbGlicmFyeSh0aWR5dmVyc2UpIApgYGAKClRoZSBwYWNrYWdlIGF1dG9tYXRpY2FsbHkgbG9hZCBhIHBhcnQgb2YgYHRpZHl2ZXJzZWAsIGUuZy4sIGBkcGx5cmAsIGBnZ3Bsb3RgLCAuLi4uIFNpbmNlIGl0IHdvcmtzIHdlbGwgd2l0aCB0aGUgc2NoZW1lYHRpZHl2ZXJzZWAsIGl0IGlzIGJldHRlciB0byBsb2FkIGB0aWR5dmVyc2VgIHdpdGggaXQuCgpUaGUgY3JlYXRvciBvZiB0aGlzIHBhY2thZ2UgYWxzbyBzdWdnZXN0cyBsb2FkaW5nIHBhY2thZ2VzIGBwbG1gIGZvciBwYW5lbHMgb2YgZGF0YSwgYW5kIGB0ZXhyZWdgIGZvciBkaXNwbGF5aW5nIG1vZGVscywgYnV0IGxldCB1cyBzdGFydCB3aXRob3V0IHRoZW0gdW50aWwgd2UgYWN0dWFsbHkgdXNlIHRoZW0uIEZvciBwYW5lbCBkYXRhLCBzZWUsIGZvciBleGFtcGxlLCB0aGUgc2l0ZV0oaHR0cHM6Ly93d3cuYXB0ZWNoLmNvbS9ibG9nL2ludHJvZHVjdGlvbi10by10aGUtZnVuZGFtZW50YWxzLW9mLXBhbmVsLWRhdGEvKS4KCiMjIENvcmUgZnVuY3Rpb25zCgojIyMgTGlzdCBvZiBjb3JlIGZ1bmN0aW9ucwoKSW4gdGhpcyBwYWNrYWdlLCBgY2hhcnRgIGlzIGNsb3NlIHRvIGRhdGEsIGFuZCBgY2hhcnQgaWRgIGlzIGEgZGF0YSBpbmRpY2F0b3IuCgoqIG93aWQ6IEdldCBhIGRhdGFzZXQgdXNlZCBpbiBhbiBPV0lEIGNoYXJ0Ciogb3dpZF9jb3ZpZDogR2V0IHRoZSBPdXIgV29ybGQgaW4gRGF0YSBjb3ZpZC0xOSBkYXRhc2V0Ciogb3dpZF9zZWFyY2g6IFNlYXJjaCB0aGUgZGF0YSBzb3VyY2VzIHVzZWQgaW4gT1dJRCBjaGFydHMKKiBvd2lkX3NvdXJjZTogQSBmdW5jdGlvbiB0byBnZXQgc291cmNlIGluZm9ybWF0aW9uIGZyb20gYW4gT1dJRCBkYXRhc2V0IGFuZCBkaXNwbGF5IGl0IGluIHRoZSBSIGNvbnNvbGUuCiogcGFsX293aWQ6IENvbG91ciBwYWxldHRlcyBiYXNlZCBvbiB0aGUgY29sb3VycyB1c2VkIGJ5IE91ciBXb3JsZCBpbiBEYXRhCiogdmlld19jaGFydDogQSBmdW5jdGlvbiB0aGF0IG9wZW5zIHRoZSBvcmlnaW5hbCBPV0lEIGNoYXJ0IGluIHlvdXIgYnJvd3NlcgoqIHdvcmxkX21hcF9kYXRhOiBGdW5jdGlvbiB0aGF0IHJldHVybnMgYSBzaW1wbGUgZmVhdHVyZSBjb2xsZWN0aW9uIG9mIGNsYXNzIHNmLiBNYXAgZGF0YSBpcyBmcm9tIG5hdHVyYWxlYXJ0aGRhdGEuY29tLiBEZXNpZ25lZCB0byBiZSB1c2VkIGludGVybmFsbHkuCgojIyMgVXNhZ2UKCiMjIyMgYG93aWRfc2VhcmNoYAoKU2VhcmNoIHRoZSBkYXRhIHNvdXJjZXMgdXNlZCBpbiBPV0lEIGNoYXJ0cwoKYGBgCm93aWRfc2VhcmNoKHRlcm0pCmBgYAoKKiBFeGFtcGxlCgpTaW5jZSB0aGUgb3V0cHV0IGlzIGxvbmcsIEkgY3V0IGl0IG9mZiB0byB0aGUgZmlyc3Qgc2l4IHJvd3MgdXNpbmcgYGhlYWQoKWAuCgpgYGB7cn0Kb3dpZF9zZWFyY2goImVtaXNzaW9ucyIpICU+JSBoZWFkKCkKYGBgCgpBIG1hdHJpeCBpcyByZXR1cm5lZC4gSWYgdGhlIGxpc3QgaXMgbG9uZywgaXQgaXMgZWFzaWVyIHRvIHNlZSB0aGUgcGFpcnMgb2YgdGhlIHRpdGxlcyBhbmQgY2hhcnRfaWRzIGJ5IGFkZGluZyBgYXNfdGliYmxlKClgLgoKYGBge3J9Cm93aWRfc2VhcmNoKCJlbWlzc2lvbnMiKSAlPiUgYXNfdGliYmxlKCkKYGBgCgpJZiB0aGUgbGlzdCBpcyBub3QgbG9uZywgeW91IGRvIG5vdCBuZWVkIHRvIGFkZCBgYXNfdGliYmxlKClgLiBIb3dldmVyLCBub3RlIHRoYXQgeW91IG5lZWQgdG8ga2VlcCBpbiBtaW5kIHRoYXQgdGhlIHRpdGxlIGFuZCB0aGUgY2hhcnRfaWQgY29uc2lzdHMgb2YgYSBwYWlyLCBhbmQgeW91IG5lZWQgdG8gdXNlIHRoZSBjaGFydF9pZCB0byBkb3dubG9hZCB0aGUgZGF0YSB1c2luZyBgb3dpZGAuCgpgYGB7cn0Kb3dpZF9zZWFyY2goImh1bWFuIHJpZ2h0cyIpCmBgYAoKCiMjIyMgYG93aWRgCgpHZXQgYSBkYXRhc2V0IHVzZWQgaW4gYW4gT1dJRCBjaGFydAoKYGBgCm93aWQoY2hhcnRfaWQgPSBOVUxMLCByZW5hbWUgPSBOVUxMLCB0aWR5LmRhdGUgPSBUUlVFLCAuLi4pCmBgYAoKYGNoYXJkX2lkYDogVGhlIGNoYXJ0X2lkIGFzIHJldHVybmVkIGJ5IG93aWRfc2VhcmNoLCB3aGljaCBpcyBjb21iaW5lZCB3aXRoICctJy4gRG9uJ3QgbWl4IHVwIHdpdGggdGhlIGNoYXJ0IHRpdGxlcy4KCmByZW5hbWVgOiBSZW5hbWUgdGhlIHZhbHVlIGNvbHVtbi4gQ3VycmVudGx5IG9ubHkgd29ya3MgaWYgdGhlaXIgaXMganVzdCBvbmUgdmFsdWUgY29sLSB1bW4uCgoqIEV4YW1wbGUKCmBgYHtyIGNhc2g9VFJVRX0KZW1pc3Npb25zIDwtIG93aWQoInBlci1jYXBpdGEtZ2hnLWVtaXNzaW9ucyIpCmBgYAoKYGBge3J9CmVtaXNzaW9ucwpgYGAKCmBgYHtyIGNhc2g9VFJVRX0KcmlnaHRzIDwtIG93aWQoImh1bWFuLXJpZ2h0cy1zY29yZXMiKQpgYGAKCmBgYHtyfQpyaWdodHMKYGBgCgoqKk5vdGUuKioKCjEuIFlvdSBjYW4gdXNlIGByZW5hbWVgIHRvIGNoYW5nZSBjb2x1bW4gbmFtZXMuIEZvciBleGFtcGxlLCAKCmBgYHtyfQpvd2lkKCJwZXItY2FwaXRhLWdoZy1lbWlzc2lvbnMiLCByZW5hbWUgPSAiZ2hnUGNhcCIpCmBgYAoKMi4gU2luY2UgdW50aWwgYWZ0ZXIgaW1wb3J0aW5nIHRoZSBkYXRhLCB5b3UgbmV2ZXIga25vdyB0aGUgb3JpZ2luYWwgY29sdW1uIG5hbWUsIGFuZCBob3cgbWFueSBjb2x1bW5zIGFyZSBmb3IgaW5kaWNhdG9ycy4gSXQgaXMgbmF0dXJhbCB0byBjaGFuZ2UgY29sdW1uIG5hbWVzIHVzaW5nIGBkcHlyOjpyZW5hbWVgLiBJbiB0aGUgbmV4dCBleGFtcGxlLCBJIHVzZWQgYFRvdGFsIGluY2x1ZGluZyBMVUNGYC4gSG93ZXZlciwgJ1RvdGFsIGluY2x1ZGluZyBMVUNGJyBhbmQgIlRvdGFsIGluY2x1ZGluZyBMVUNGIiB3b3JrIGFzIHdlbGwuCgpgYGB7cn0KZW1pc3Npb25zICU+JSByZW5hbWUoZ2hnUGNhcCA9IGBUb3RhbCBpbmNsdWRpbmcgTFVDRmApCmBgYAoKMy4gSWYgdGhlcmUgYXJlIG1vcmUgdGhhbiBvbmUgdmFyaWFibGVzIHRvIHJlbmFtZSwgdXNlIHZlY3RvciBub3RhdGlvbiBhcyBmb2xsb3dzLiBIZXJlIGB0b3BfbigxKWAgaXMgc2FtZSBhcyBgc2xpY2UoMSlgLCBhbmQgZ2l2ZXMgdGhlIGZpcnN0IHJvdyBvbmx5LgoKYGBge3J9Cm93aWQoImVsZWN0b3JhbC1kZW1vY3JhY3kiKSAlPiUgdG9wX24oMSkKYGBgCgpgYGB7cn0Kb3dpZCgiZWxlY3RvcmFsLWRlbW9jcmFjeSIsIHJlbmFtZSA9IGMoImVsZWN0b3JhbF9kZW1vY3JhY3kiLCAidmRlbV9oaWdoIiwgInZkZW1fbG93IikpCmBgYAoKCjQuIFlvdSBjYW4gdXNlIGBkcGx5cjo6cmVuYW1lYCwgYW5kIGtlZXAgdGhlIHJlY29yZCBvZiByZW5hbWluZyBjb2x1bW4gbmFtZXMuCgpgYGB7cn0KKGRlbW9jcmFjeSA8LSBvd2lkKCJlbGVjdG9yYWwtZGVtb2NyYWN5IikpCmBgYAoKCmBgYHtyfQpkZW1vY3JhY3kgPC0gZGVtb2NyYWN5ICU+JSAKICByZW5hbWUoYGVsZWN0b3JhbF9kZW1vY3JhY3lgID0gYEVsZWN0b3JhbCBkZW1vY3JhY3lgLCAgCiAgICAgICAgIGB2ZGVtX2hpZ2hgID0gYGVsZWN0ZGVtX3ZkZW1faGlnaF9vd2lkYCwgCiAgICAgICAgIGBlbGVjdGRlbV92ZGVtX2xvd19vd2lkYCA9IGBlbGVjdGRlbV92ZGVtX2xvd19vd2lkYCkKZGVtb2NyYWN5CmBgYAoKCiMjIyMgYG93aWRfc291cmNlYAoKQSBmdW5jdGlvbiB0byBnZXQgc291cmNlIGluZm9ybWF0aW9uIGZyb20gYW4gT1dJRCBkYXRhc2V0IGFuZCBkaXNwbGF5IGl0IGluIHRoZSBSIGNvbnNvbGUuCgpgYGAKb3dpZF9zb3VyY2UoZGF0YSkKYGBgCgoqIEV4YW1wbGUKCmBgYHtyfQpvd2lkX3NvdXJjZShlbWlzc2lvbnMpCmBgYAoKCmBgYHtyfQpvd2lkX3NvdXJjZShyaWdodHMpCmBgYAoKCgojIyMjIGB2aWV3X2NoYXJ0YAoKQSBmdW5jdGlvbiB0aGF0IG9wZW5zIHRoZSBvcmlnaW5hbCBPV0lEIGNoYXJ0IGluIHlvdXIgYnJvd3NlcgoKYGBgCnZpZXdfY2hhcnQoeCkKYGBgCgoqIGB4YCBFaXRoZXIgYSB0aWJibGUgcmV0dXJuZWQgYnkgYG93aWQoKWAsIG9yIGEgYGNoYXJ0X2lkYC4KCiogRXhhbXBsZQoKVGhlIGZpcnN0IG9uZSB1c2VzIHRoZSBjaGFydCwgaS5lLiwgdGhlIHRpYmJsZSByZXR1cm5lZCBieSBgb3dpZCgpYCwgYW5kIHRoZSBzZWNvbmQsIGBjaGFydF9pZGAuIFlvdSBjYW4gYWxzbyBlbWJlZCBpbiB5b3VyIFIgTWFya2Rvd24gZmlsZSBieSBjb3B5aW5nIEVtYmVkIGBpZnJhbWVgIGNsaW5rIGZyb20gYFNoYXJlYCBib3R0b24gYXQgdGhlIGJvdHRvbSByaWdodCBjb3JuZXIuCgpgYGB7ciBldmFsPUZBTFNFfQpmaXJlYXJtX3N1aWNpZGUgPC0gb3dpZCgic3VpY2lkZS1yYXRlLWJ5LWZpcmVhcm0iKQogICAgdmlld19jaGFydChmaXJlYXJtX3N1aWNpZGUpCmBgYAoKPGlmcmFtZSBzcmM9Imh0dHBzOi8vb3Vyd29ybGRpbmRhdGEub3JnL2dyYXBoZXIvc3VpY2lkZS1yYXRlLWJ5LWZpcmVhcm0iIGxvYWRpbmc9ImxhenkiIHN0eWxlPSJ3aWR0aDogMTAwJTsgaGVpZ2h0OiA2MDBweDsgYm9yZGVyOiAwcHggbm9uZTsiPjwvaWZyYW1lPgoKYGBge3IgZXZhbD1GQUxTRX0Kdmlld19jaGFydCgiZWxlY3RvcmFsLWRlbW9jcmFjeSIpCmBgYAoKPGlmcmFtZSBzcmM9Imh0dHBzOi8vb3Vyd29ybGRpbmRhdGEub3JnL2dyYXBoZXIvZWxlY3RvcmFsLWRlbW9jcmFjeT9jb3VudHJ5PUFSR35BVVN+QldBfkNITiIgbG9hZGluZz0ibGF6eSIgc3R5bGU9IndpZHRoOiAxMDAlOyBoZWlnaHQ6IDYwMHB4OyBib3JkZXI6IDBweCBub25lOyI+PC9pZnJhbWU+CgpgYGB7ciBldmFsPUZBTFNFfQp2aWV3X2NoYXJ0KCJzaGFyZS1vZi1pbmRpdmlkdWFscy11c2luZy10aGUtaW50ZXJuZXQiKQpgYGAKCjxpZnJhbWUgc3JjPSJodHRwczovL291cndvcmxkaW5kYXRhLm9yZy9ncmFwaGVyL3NoYXJlLW9mLWluZGl2aWR1YWxzLXVzaW5nLXRoZS1pbnRlcm5ldCIgbG9hZGluZz0ibGF6eSIgc3R5bGU9IndpZHRoOiAxMDAlOyBoZWlnaHQ6IDYwMHB4OyBib3JkZXI6IDBweCBub25lOyI+PC9pZnJhbWU+CgoKIyMjIyBgcGFsX293aWRgCgpDb2xvdXIgcGFsZXR0ZXMgYmFzZWQgb24gdGhlIGNvbG91cnMgdXNlZCBieSBPdXIgV29ybGQgaW4gRGF0YQoKIyMjIyBgb3dpZF9jb3ZpZGAKCm93aWRfY292aWQ6IEdldCB0aGUgT3VyIFdvcmxkIGluIERhdGEgY292aWQtMTkgZGF0YXNldAoKYGBgCm93aWRfY292aWQoKQpgYGAKClNlZSB0aGUgZGV0YWlsIGF0IHRoZSBbR2l0SHViIHNpdGVdKGh0dHBzOi8vZ2l0aHViLmNvbS9vd2lkL2NvdmlkLTE5LWRhdGEvdHJlZS9tYXN0ZXIvcHVibGljL2RhdGEjZGF0YS1vbi1jb3ZpZC0xOS1jb3JvbmF2aXJ1cy1ieS1vdXItd29ybGQtaW4tZGF0YSkuCgoqIEV4YW1wbGUKCmBgYHtyIGNhc2g9VFJVRX0KY292aWQgPC0gb3dpZF9jb3ZpZCgpCmBgYAoKYGBge3J9CmNvdmlkICU+JSBmaWx0ZXIobG9jYXRpb24gPT0gIkphcGFuIikKYGBgCgojIEV4YW1wbGVzCgpUaGUgZm9sbG93aW5nIGlzIGJhc2VkIG9uIHRoZSBwcmVzZW50YXRpb24gYW5kIHRoZSBmaXJzdCB0d28gUiBOb3RlYm9vayBmaWxlcyBjcmVhdGVkIGJ5IFByb2Zlc3NvciBLYWl6b2ppLgoKIyMgSHVtYW4gUmlnaHRzLSBtb2RpZmllZCBmcm9tICBSRUFETUUKCkxldHMgdXNlIHRoZSBjb3JlIGZ1bmN0aW9ucyB0byBnZXQgZGF0YSBvbiBob3cgaHVtYW4gcmlnaHRzIGhhdmUgY2hhbmdlZCBvdmVyIHRpbWUuIEZpcnN0IGJ5IHNlYXJjaGluZyBmb3IgY2hhcnRzIG9uIGh1bWFuIHJpZ2h0cy4KCmBgYHtyfQpvd2lkX3NlYXJjaCgiaHVtYW4gcmlnaHRzIikgJT4lIGFzX3RpYmJsZSgpCmBgYAoKTGV04oCZcyB1c2UgdGhlIGh1bWFuIHJpZ2h0cyBwcm90ZWN0aW9uIGRhdGFzZXQuCgpgYGB7cn0KcmlnaHRzIDwtIG93aWQoImh1bWFuLXJpZ2h0cy1wcm90ZWN0aW9uIikKcmlnaHRzCmBgYAoKZ2dwbG90MiBtYWtlcyBpdCBlYXN5IHRvIHZpc3VhbGlzZSBvdXIgZGF0YS4KCgpgYGB7cn0KcmlnaHRzICU+JSAKICBmaWx0ZXIoZW50aXR5ICVpbiUgYygiVW5pdGVkIEtpbmdkb20iLCAiRnJhbmNlIiwgIlVuaXRlZCBTdGF0ZXMiLCAiSmFwYW4iKSkgJT4lICAKICBnZ3Bsb3QoYWVzKHllYXIsIGBIdW1hbiByaWdodHMgcHJvdGVjdGlvbmAsIGNvbG91ciA9IGVudGl0eSkpICsKICBnZW9tX2xpbmUoKQpgYGAKCgojIyBJbnRlcm5ldCAtIG1vZGlmaWVkIGZyb20gdmlnbmV0dGUKCgpgYGB7cn0Kb3dpZF9zZWFyY2goImludGVybmV0IikgJT4lIGFzX3RpYmJsZSgpCmBgYAoKR2V0IGEgZGF0YXNldCB1c2VkIGluIGFuIE9XSUQgY2hhcnQuCgoKYGBge3J9CmludGVybmV0IDwtIG93aWQoInNoYXJlLW9mLWluZGl2aWR1YWxzLXVzaW5nLXRoZS1pbnRlcm5ldCIsIHJlbmFtZSA9ICJpbnRlcm5ldF91c2UiKQppbnRlcm5ldApgYGAKCkdldCBzb3VyY2UgaW5mb3JtYXRpb24gb24gYW4gT1dJRCBkYXRhc2V0CgpgYGB7cn0Kb3dpZF9zb3VyY2UoaW50ZXJuZXQpCmBgYAoKQSBmdW5jdGlvbiB0aGF0IG9wZW5zIHRoZSBvcmlnaW5hbCBPV0lEIGNoYXJ0IGluIHlvdXIgYnJvd3Nlci4KCmBgYHtyIGV2YWw9RkFMU0V9CnZpZXdfY2hhcnQoaW50ZXJuZXQpCmBgYAoKPGlmcmFtZSBzcmM9Imh0dHBzOi8vb3Vyd29ybGRpbmRhdGEub3JnL2dyYXBoZXIvc2hhcmUtb2YtaW5kaXZpZHVhbHMtdXNpbmctdGhlLWludGVybmV0IiBsb2FkaW5nPSJsYXp5IiBzdHlsZT0id2lkdGg6IDEwMCU7IGhlaWdodDogNjAwcHg7IGJvcmRlcjogMHB4IG5vbmU7Ij48L2lmcmFtZT4KClBsb3QgYW4gb3dpZCBkYXRhc2V0CgpgYGB7cn0Kb3dpZF9wbG90KGludGVybmV0LCBmaWx0ZXIgPSAiV29ybGQiKSArCiAgbGFicyh0aXRsZSA9ICJTaGFyZSBvZiB0aGUgV29ybGQgUG9wdWxhdGlvbiB1c2luZyB0aGUgSW50ZXJuZXQiKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cyA9IGMoMCwgMTAwKSkrCiAgdGhlbWVfb3dpZCgpCmBgYAoKCmBgYHtyfQpvd2lkX3Bsb3QoaW50ZXJuZXQsIHN1bW1hcmlzZSA9IEZBTFNFLCBmaWx0ZXIgPSBjKCJVbml0ZWQgS2luZ2RvbSIsICJTcGFpbiIsICJSdXNzaWEiLCAiRWd5cHQiLCAiTmlnZXJpYSIpKSArCiAgbGFicyh0aXRsZSA9ICJTaGFyZSBvZiBQb3B1bGF0aW9uIHdpdGggVXNpbmcgdGhlIEludGVybmV0IikgKwogIHNjYWxlX3lfY29udGludW91cyhsaW1pdHMgPSBjKDAsIDEwMCksIGxhYmVscyA9IHNjYWxlczo6bGFiZWxfbnVtYmVyKHN1ZmZpeCA9ICIlIikpICMgVGhlIGxhYmVscyBhcmd1bWVudCBhbGxvd3MgeW91IHRvIG1ha2UgaXQgY2xlYXIgdGhhdCB0aGUgdmFsdWUgaXMgYSBwZXJjZW50YWdlCmBgYAoKCmNyZWF0aW5nIGEgY2hvcm9wbGV0aCBtYXAgCgpgYGB7cn0Kb3dpZF9tYXAoaW50ZXJuZXQsIHllYXIgPSAyMDE3KSArCiAgbGFicyh0aXRsZSA9ICJTaGFyZSBvZiBQb3B1bGF0aW9uIFVzaW5nIHRoZSBJbnRlcm5ldCwgMjAxNyIpCmBgYAoKIyMgRGVtb2NyYWN5IC0gbW9kaWZpZWQgZnJvbSB2aWduZXR0ZQoKYGBge3J9Cm93aWRfc2VhcmNoKCJkZW1vY3JhYyIpICU+JSBhc190aWJibGUoKQpgYGAKCmBgYHtyfQpkZW1vY3JhY3kgPC0gb3dpZCgiZWxlY3RvcmFsLWRlbW9jcmFjeSIsIHJlbmFtZSA9IGMoImVsZWN0b3JhbF9kZW1vY3JhY3kiLCAidmRlbV9oaWdoIiwgInZkZW1fbG93IikpCmRlbW9jcmFjeQpgYGAKCmBgYHtyfQpvd2lkX3NvdXJjZShkZW1vY3JhY3kpCmBgYAoKYGBge3J9Cm93aWRfbWFwKGRlbW9jcmFjeSwgeWVhciA9IDIwMTUsIHBhbGV0dGUgPSAiWWxHbiIpICsKICBsYWJzKHRpdGxlID0gIkVsZWN0b3JhbCBEZW1vY3JhY3kiKQpgYGAKCmBgYHtyfQpvd2lkX3Bsb3QoZGVtb2NyYWN5LCBzdW1tYXJpc2UgPSBGQUxTRSwgZmlsdGVyID0gYygiVW5pdGVkIEtpbmdkb20iLCAiU3BhaW4iLCAiUnVzc2lhIiwgIkVneXB0IiwgIk5pZ2VyaWEiKSkgKwogIGxhYnModGl0bGUgPSAiZWxlY3RvcmFsLWRlbW9jcmFjeSIpICsKICBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzID0gYygwLCAxKSwgbGFiZWxzID0gc2NhbGVzOjpsYWJlbF9udW1iZXIoc3VmZml4ID0gIiUiKSkgIyBUaGUgbGFiZWxzIGFyZ3VtZW50IGFsbG93cyB5b3UgdG8gbWFrZSBpdCBjbGVhciB0aGF0IHRoZSB2YWx1ZSBpcyBhIHBlcmNlbnRhZ2UKIz4gV2FybmluZzogJ3NjYWxlX2NvbG91cl9vd2lkJyBpcyBkZXByZWNhdGVkLgojPiBTZWUgaGVscCgiRGVwcmVjYXRlZCIpCmBgYAoKYGBge3J9CmdkcCA8LSBvd2lkKCJnZHAtcGVyLWNhcGl0YS13b3JsZGJhbmsiLCByZW5hbWUgPSAiZ2RwIikKCmdvdl9leHAgPC0gb3dpZCgidG90YWwtZ292LWV4cGVuZGl0dXJlLWdkcC13ZGkiLCByZW5hbWUgPSAiZ292X2V4cCIpCgphZ2VfZGVwIDwtIG93aWQoImFnZS1kZXBlbmRlbmN5LXJhdGlvLW9mLXdvcmtpbmctYWdlLXBvcHVsYXRpb24iLCByZW5hbWUgPSAiYWdlX2RlcCIpCgp1bmVtcGxveW1lbnQgPC0gb3dpZCgidW5lbXBsb3ltZW50LXJhdGUiLCByZW5hbWUgPSAidW5lbXAiKQpgYGAKCk11dGF0aW5nIGpvaW5zCgpsZWZ0X2pvaW4oKTogaW5jbHVkZXMgYWxsIHJvd3MgaW4geC4KCioqUmVmZXJlbmNlcyoqCgoqIFNlZSBodHRwczovL2RwbHlyLnRpZHl2ZXJzZS5vcmcvcmVmZXJlbmNlL211dGF0ZS1qb2lucy5odG1sLgoqIFBvc2l0IFByaW1lcnMgLSBUaWR5IHlvdXIgZGF0YTogaHR0cHM6Ly9wb3NpdC5jbG91ZC9sZWFybi9wcmltZXJzLzQKICAtIEpvaW4gRGF0YSBTZXRzOiBodHRwczovL3Bvc2l0LmNsb3VkL2xlYXJuL3ByaW1lcnMvNC4zCgpgYGB7cn0KZGF0YSA8LSBpbnRlcm5ldCAlPiUgCiAgbGVmdF9qb2luKGRlbW9jcmFjeSkgJT4lIAogIGxlZnRfam9pbihnZHApICU+JSAKICBsZWZ0X2pvaW4oZ292X2V4cCkgJT4lIAogIGxlZnRfam9pbihhZ2VfZGVwKSAlPiUgCiAgbGVmdF9qb2luKHVuZW1wbG95bWVudCkKYGBgCgpEcmF3aW5nIHNjYXR0ZXIgcGxvdAoKYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KZGF0YSAlPiUgCiAgZmlsdGVyKHllYXIgPT0gMjAxNSkgJT4lIAogIGdncGxvdChhZXMoaW50ZXJuZXRfdXNlLCBlbGVjdG9yYWxfZGVtb2NyYWN5KSkgKwogIGdlb21fcG9pbnQoY29sb3VyID0gIiM1NzY3N0QiLCBuYS5ybSA9IFRSVUUpICsKICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBjb2xvdXIgPSAiI0RDNUU3OCIsIG5hLnJtID0gVFJVRSkgKwogIGxhYnModGl0bGUgPSAiUmVsYXRpb25zaGlwIEJldHdlZW4gSW50ZXJuZXQgVXNlIGFuZCBlbGVjdG9yYWxfZGVtb2NyYWN5IiwgeCA9ICJJbnRlcm5ldCBVc2UiLCB5ID0gImVsZWN0b3JhbF9kZW1vY3JhY3kiKSArCiAgdGhlbWVfb3dpZCgpCmBgYAoKCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CmRhdGEgJT4lIAogIGZpbHRlcih5ZWFyID09IDIwMTUpICU+JSAKICBnZ3Bsb3QoYWVzKGdkcCwgaW50ZXJuZXRfdXNlKSkgKwogIGdlb21fcG9pbnQoY29sb3VyID0gImJsdWUiKSArCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImdhbSIsIGNvbG91ciA9ICJyZWQiLCBsZXZlbCA9IDAuMCkgKwogIGxhYnModGl0bGUgPSAiUmVsYXRpb25zaGlwIEJldHdlZW4gSW50ZXJuZXQgVXNlIGFuZCBHRFAiLCB4ID0gIkdEUCIsIHkgPSAiSW50ZXJuZXQgVXNlIikKYGBgCgoKYGBge3J9Cm1vZGVsMSA8LSBsbShlbGVjdG9yYWxfZGVtb2NyYWN5IH4gaW50ZXJuZXRfdXNlLCBkYXRhKQpzdW1tYXJ5KG1vZGVsMSkKYGBgCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9Cm1vZGVsMiA8LSBsbShnZHAgfiBpbnRlcm5ldF91c2UsIGRhdGEpCnN1bW1hcnkobW9kZWwyKQpgYGAKCkNyZWF0aW5nIGEgdGFibGUgb2YgdGhlIHJlc3VsdHMgb2YgdGhlIHJlZ3Jlc3Npb24gYW5hbHlzaXMgdXNpbmcgYHRleHJlZ2AuCkZvciB0aGUgZmlyc3QgdGltZSwgaW5zdGFsbCB0aGUgcGFjYWdlIGB0ZXhyZWdgLgoKYGBge3IgZXZhbD1GQUxTRX0KaW5zdGFsbC5wYWNrYWdlcygidGV4cmVnIikKYGBgCgoKYGBge3J9CmxpYnJhcnkodGV4cmVnKQpgYGAKCgpgYGB7cn0KbW9kZWxzIDwtIGxpc3QoIk1vZGVsIDEiID0gbW9kZWwxLAogICAgICAgICAgICAgICAiTW9kZWwgMiIgPSBtb2RlbDIpCnNjcmVlbnJlZyhtb2RlbHMsIHN0YXJzID0gTlVMTCkKYGBgCgoK